﻿
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.Linq;

namespace Common
{
    public class CommonFun
    {
        private static object obj = new object();
        private static int GuidInt { get { return Guid.NewGuid().GetHashCode(); } }
        private static string GuidIntStr { get { return Math.Abs(GuidInt).ToString(); } }

        /// <summary>
        /// 生成
        /// </summary>
        /// <param name="mark">前缀</param>
        /// <param name="timeType">时间精确类型  1 日,2 时,3 分，4 秒(默认) </param>
        /// <param name="id">id 小于或等于0则随机生成id</param>
        /// <returns></returns>
        public static string Gener(string mark, int timeType = 4, int id = 0)
        {
            lock (obj)
            {
                var number = mark;
                var ticks = (DateTime.Now.Ticks - GuidInt).ToString();
                int fillCount = 0;//填充位数

                number += GetTimeStr(timeType, out fillCount);
                if (id > 0)
                {
                    number += ticks.Substring(ticks.Length - (fillCount + 3)) + id.ToString().PadLeft(10, '0');
                }
                else
                {
                    number += ticks.Substring(ticks.Length - (fillCount + 3)) + GuidIntStr.PadLeft(10, '0');
                }
                return number;
            }
        }

        /// <summary>
        /// 生成
        /// </summary>
        /// <param name="mark">前缀</param>
        /// <param name="timeType">时间精确类型  1 日,2 时,3 分，4 秒(默认)</param>
        /// <param name="id">id 小于或等于0则随机生成id</param>
        /// <returns></returns>
        public static string GenerLong(string mark, int timeType = 4, long id = 0)
        {
            lock (obj)
            {
                var number = mark;
                var ticks = (DateTime.Now.Ticks - GuidInt).ToString();
                int fillCount = 0;//填充位数

                number += GetTimeStr(timeType, out fillCount);
                if (id > 0)
                {
                    number += ticks.Substring(ticks.Length - fillCount) + id.ToString().PadLeft(19, '0');
                }
                else
                {
                    number += GuidIntStr.PadLeft(10, '0') + ticks.Substring(ticks.Length - (9 + fillCount));
                }
                return number;
            }
        }

        /// <summary>
        /// 获取时间字符串
        /// </summary>
        /// <param name="timeType">时间精确类型  1 日,2 时,3 分，4 秒(默认)</param>
        /// <param name="fillCount">填充位数</param>
        /// <returns></returns>
        private static string GetTimeStr(int timeType, out int fillCount)
        {
            var time = DateTime.Now;
            if (timeType == 1)
            {
                fillCount = 6;
                return time.ToString("yyyyMMdd");
            }
            else if (timeType == 2)
            {
                fillCount = 4;
                return time.ToString("yyyyMMddHH");
            }
            else if (timeType == 3)
            {
                fillCount = 2;
                return time.ToString("yyyyMMddHHmm");
            }
            else
            {
                fillCount = 0;
                return time.ToString("yyyyMMddHHmmss");
            }
        }

 

        #region 实体类 XML 

        /// <summary>
        /// 实体类转换成XML
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string XmlSerialize<T>(T obj)
        {
            using (StringWriter sw = new StringWriter())
            {
                Type t = obj.GetType();
                XmlSerializer serializer = new XmlSerializer(obj.GetType());
                serializer.Serialize(sw, obj);
                sw.Close();
                return sw.ToString();
            }
        }
        /// <summary>
        /// XML转换成实体类
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="strXML"></param>
        /// <returns></returns>
        public static T DESerializer<T>(string strXML) where T : class
        {
            try
            {
                using (StringReader sr = new StringReader(strXML))
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(T));
                    return serializer.Deserialize(sr) as T;
                }
            }
            catch (Exception ex)
            {
                return null;
            }
        }
        #endregion

        /// <summary>
        /// 经典排序签名字符串
        /// </summary>
        /// <param name="parameters"></param>
        /// <param name="isEmpty">为空包含是否</param>
        /// <param name="filters">是否过滤字段</param>
        /// <param name="filterExsits">是否过滤包含字段</param>
        /// <returns></returns>
        public static string GetSignContent(IDictionary<string, string> parameters, bool isEmpty = true, List<string> filters = null, List<string> filterExsits = null)
        {
            // 第一步：把字典按Key的字母顺序排序
            IDictionary<string, string> sortedParams = new SortedDictionary<string, string>(parameters);
            IEnumerator<KeyValuePair<string, string>> dem = sortedParams.GetEnumerator();

            // 第二步：把所有参数名和参数值串在一起
            StringBuilder query = new StringBuilder("");
            while (dem.MoveNext())
            {
                string key = dem.Current.Key;
                string value = dem.Current.Value;

                bool isNext = true;

                if (filters != null && filters.Count > 0)
                {
                    string temp1 = key.ToLower();
                    foreach (var item0 in filters)
                    {
                        string item2 = item0.ToLower();

                        if (temp1 == item2)
                        {
                            isNext = false;
                        }
                    }
                }
                if (filterExsits != null && filterExsits.Count > 0)
                {
                    string temp1 = key.ToLower();
                    foreach (var item0 in filterExsits)
                    {
                        string item2 = item0.ToLower();

                        if (item2.IndexOf(temp1) > -1)
                        {
                            isNext = false;
                        }
                    }
                }


                if (!string.IsNullOrEmpty(key) && isNext)
                {
                    if (isEmpty)
                    {
                        query.Append(key).Append("=").Append(value).Append("&");
                    }
                    else
                    {
                        if (!string.IsNullOrEmpty(value))
                        {
                            query.Append(key).Append("=").Append(value).Append("&");
                        }
                    }

                }
            }
            string content = query.ToString().Substring(0, query.Length - 1);

            return content;
        }


        #region 实体类 字典
        /// <summary>
        /// 实体类转字典
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="model"></param>
        /// <returns></returns>
        public static Dictionary<string, object> GetModelByDic<T>(T model) where T : class
        {
            return Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, object>>(Newtonsoft.Json.JsonConvert.SerializeObject(model));
        }
        /// <summary>
        /// 字典转实体类
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dic"></param>
        /// <returns></returns>
        public static T GetDicByModel<T>(Dictionary<string, object> dic) where T : class
        {
            return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(Newtonsoft.Json.JsonConvert.SerializeObject(dic));
        }
        #endregion

        /// <summary>
        /// 记录日志
        /// </summary>
        /// <param name="strMessage">记录消息</param>
        /// <param name="fileType">文件夹，可以默认为空不影响</param>
        public static void LogInfoWrite(string strMessage, string fileType = "")
        {
            if (!string.IsNullOrWhiteSpace(fileType))
            {
                fileType = fileType + "/";
            }
            DateTime time = DateTime.Now;
            //string path = AppDomain.CurrentDomain.BaseDirectory + @"InfoLogs\" + fileType;
            string path = "/root/data/InfoLogs/" + fileType;
            if (!Directory.Exists(path))
                Directory.CreateDirectory(path);

            string fileFullPath = path + time.ToString("yyyy-MM-dd") + ".txt";
            StringBuilder str = new StringBuilder();
            str.Append("Time:    " + time.ToString() + "\r\n");
            str.Append("Message: " + strMessage + "\r\n");
            str.Append("-----------------------------------------------------------\r\n\r\n");
            StreamWriter sw;
            if (!File.Exists(fileFullPath))
            {
                sw = File.CreateText(fileFullPath);
            }
            else
            {
                sw = File.AppendText(fileFullPath);
            }
            sw.WriteLine(str.ToString());
            sw.Close();
        }

        /// <summary>
        /// 创建文件到项目根目录
        /// </summary>
        /// <returns></returns>
        public static string CreateProjectRootFilePath(string filePath)
        {

            if (string.IsNullOrWhiteSpace(filePath))
            {
                filePath = "DefaultPath";
            }

            string path = AppDomain.CurrentDomain.BaseDirectory + "wwwroot/" + filePath;
            if (!Directory.Exists(path))
                Directory.CreateDirectory(path);

            return path;
        }

        /// <summary>
        /// 校验是否数字类型
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static bool CheckNumber(object obj)
        {
            try
            {
                Convert.ToDecimal(obj);

                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }


        public static DateTime? ConvertTime(object obj)
        {
            try
            {
                return Convert.ToDateTime(obj);
            }
            catch (Exception)
            {
                return null;
            }
        }

        public static int? ConvertInt(object obj)
        {
            try
            {
                return Convert.ToInt32(obj);
            }
            catch (Exception)
            {
                return null;
            }
        }

        public static decimal? ConvertDecimal(object obj)
        {
            try
            {
                return Convert.ToDecimal(obj);
            }
            catch (Exception)
            {
                return null;
            }
        }

    }


}
